/*
 * Copyright (C) 2011 Lavettacn Xiao (lavettacn@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lavettacn.android.app.sociallessness.service.renren;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;

import com.lavettacn.android.app.sociallessness.R;
import com.lavettacn.android.app.sociallessness.fragment.LoginDialogFragment;
import com.lavettacn.android.app.sociallessness.service.BaseService;
import com.lavettacn.android.app.sociallessness.util.Debug;
import com.lavettacn.android.app.sociallessness.view.WebViewDialogListener;

public final class Renren implements BaseService {

    public static final String DEFAULT_REDIRECT_URI = "http://graph.renren.com/oauth/login_success.html";
    public static final String CANCEL_URI = "rrconnect://cancel";
    public static final String LOGIN_DENY_URI = "http://graph.renren.com/login_deny/";
    public static final String DISPLAY_URI = "display";
    public static final String AUTHORIZE_URL = "https://graph.renren.com/oauth/authorize";

    private static final String TAG = "Renren";
    private static final String[] DEFAULT_PERMISSIONS = { 
        "publish_feed",
        "create_album",
        "photo_upload",
        "read_user_album",
        "status_update"
        };
    private static final String APP_ID = "171063";
    private static final String API_KEY = "e86c1a5420644b89a5486fe9b3103f93";
    private static final String SECRET_KEY = "a7ce60d033f542ff8b8bacd787813c9d";
    private static final String RESPONSE_TYPE = "token";
    private static final String DISPLAY = "touch";
    private Context mContext;

    public Renren(Context context) {
        mContext = context;
    }

    public void login(FragmentActivity activity) {
        Debug.logD(TAG, " : login");
        CookieSyncManager.createInstance(activity);
        Bundle params = new Bundle();
        params.putString("client_id", API_KEY);
        params.putString("redirect_uri", DEFAULT_REDIRECT_URI);
        params.putString("response_type", RESPONSE_TYPE);
        params.putString("display", DISPLAY);

        String scope = TextUtils.join(" ", DEFAULT_PERMISSIONS);
        params.putString("scope", scope);

        String url = AUTHORIZE_URL + "?" + encodeUrl(params);
        if (activity.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
        } else {
            LoginDialogFragment newFragment = LoginDialogFragment.newInstance(
                    activity.getString(R.string.renren_service_name_txt), url,
                    new RenrenLoginListener());
            FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
            Fragment prev = activity.getSupportFragmentManager().findFragmentByTag(LoginDialogFragment.TAG);
            if (prev != null) {
                ft.remove(prev);
                }
            ft.addToBackStack(null);
            newFragment.show(ft, LoginDialogFragment.TAG);
        }
    }

    private String encodeUrl(Bundle parameters) {
        if (parameters == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String key : parameters.keySet()) {
            if (first) {
                first = false;
            } else {
                sb.append("&");
            }
            sb.append(key + "=" + URLEncoder.encode(parameters.getString(key)));
            //sb.append(key + "=" + parameters.getString(key));
        }
        return sb.toString();
    }

    private class RenrenLoginListener implements WebViewDialogListener {

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Debug.logD(TAG, " : shouldOverrideUrlLoading, url=", url);
            if (url.contains(DISPLAY_URI)) {
                Debug.logD(TAG, " : shouldOverrideUrlLoading, contains=", DISPLAY_URI);
                return false;
            } else if (url.startsWith(DEFAULT_REDIRECT_URI)) {
                Bundle values = parseUrl(url);

                String error = values.getString("error");
                if (error == null) {
                    error = values.getString("error_type");
                }

                if (error == null) {
                } else if (error.equals("access_denied") ||
                           error.equals("OAuthAccessDeniedException")) {
                } else {
                }

                return true;
            } else if (url.startsWith(LOGIN_DENY_URI)) {
                return true;
            } else if (url.startsWith(CANCEL_URI)) {
                return true;
            }
            mContext.startActivity(
                    new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
            return true;
        }

        @Override
        public boolean onPageStarted(WebView view, String url, Bitmap favicon) {
            boolean ret = false;
            if (url.startsWith(DEFAULT_REDIRECT_URI)) {
                Bundle values = parseUrl(url);
                String accessToken = values.getString("access_token");
                if (accessToken != null) {
                    authComplete(values);
                    ret = true;
                }
            }
            return ret;
        }

        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
            Debug.logD(TAG, " : onReceivedError, failingUrl=", failingUrl);
        }

        public void onCancel() {
        }

        private void authComplete(Bundle values) {
            
        }

        private Bundle parseUrl(String url) {
            url = url.replace("rrconnect", "http");
            url = url.replace("#", "?");
            try {
                URL u = new URL(url);
                Bundle b = decodeUrl(u.getQuery());
                b.putAll(decodeUrl(u.getRef()));
                return b;
            } catch (MalformedURLException e) {
                return new Bundle();
            }
        }

        private Bundle decodeUrl(String s) {
            Bundle params = new Bundle();
            if (s != null) {
                params.putString("url", s);
                String array[] = s.split("&");
                for (String parameter : array) {
                    String v[] = parameter.split("=");
                    if (v.length > 1) {
                        params.putString(v[0], URLDecoder.decode(v[1]));
                    }
                }
            }
            return params;
        }
    }

    public int getServiceNameId() {
        return R.string.renren_service_name_txt;
    }

    public String getServiceName() {
        return mContext.getString(R.string.renren_service_name_txt);
    }

    public int getServiceDescriptionId() {
        return R.string.renren_service_description_txt;
    }

    public String getServiceDescription() {
        return mContext.getString(R.string.renren_service_description_txt);
    }

    public int getServiceIconID() {
        return R.drawable.renren;
    }

    public Bitmap getServiceIcon() {
        return BitmapFactory.decodeResource(mContext.getResources(), R.drawable.renren);
    }

    public String getServiceType() {
        return "Renren";
    }
}
